﻿using AForge.Video;
using ComLib.ComFun;
using ComLib.ComType;
using DeviceCommon;
using LogLib;
using Newtonsoft.Json.Linq;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace PhotoCapturer
{
    public class PhotoCapturer : DeviceBase
    {
        private PhotoCameraOption _option = new PhotoCameraOption();
        private Camera.Camera _cam = new Camera.Camera();
        ShareMemory shareMem = new ShareMemory(true);
        private static object lockflag = new object();
        private Bitmap _currentFrame = null;
        private byte[] imgSourceData = null;
        private bool _bCapturing = false;
        private string _imageFilePath = "";
        public PhotoCapturer()
        {
            InitOption();
        }

        private void InitOption()
        {
            if (!File.Exists(_option.ConfigFilePath))
            {
                _option.Save();
            }
            _option.Load();
        }

        public override void Init(string param, out string outParam)
        {
            outParam = "";
            try
            {
                string camName = _option.CamName;
                int camIndex = _option.CamIndex;
                Log.WriteAsync(string.Format("配置摄像头的索引[{0}]名称[{1}]", camIndex, camName));
                int ret = _cam.InitCamera(ref camName, ref camIndex);
                if (0 == ret)
                {
                    Log.WriteAsync(string.Format("打开的摄像头的索引[{0}]名称[{1}]", camIndex, camName));
                    _cam.newFrame += NewRev;
                    _bInited = true;
                }
                else
                {
                    _error = string.Format("打开的摄像头失败。\n{0}", _cam.Error);
                    Log.WriteAsync(_error);
                    //LogDB.Error.Add(0x0100D301, _cam.Error);
                }
            }
            catch (Exception ex)
            {
                Log.WriteAsync(ex.ToString());
            }
        }

        public override bool DoAction(string param, out string outParam)
        {
            outParam = "";
            _error = "";
            JObject jsonParam = new JObject();
            try
            {
                JObject inParam = JObject.Parse(param);
                string photoIndex = (string)inParam["PhotoIndex"];
                string directory = (string)inParam["PhotoDirectory"];
                string fileName = string.Format(@"{0}\{1}.jpg", directory, photoIndex);
                if (OnPhotoTaken(fileName))
                {
                    jsonParam.Add("PhotoIndex", photoIndex);
                    jsonParam.Add("PhotoPath", fileName);
                    outParam = jsonParam.ToString();
                    Log.WriteAsync("资料翻拍成功:" + fileName);
                    return true;
                }
                else
                {
                    jsonParam.Add("PhotoIndex", "-99");
                    jsonParam.Add("PhotoPath", "");
                    outParam = jsonParam.ToString();
                    _error = "资料翻拍失败.";
                    Log.WriteAsync("资料翻拍失败.");
                    return false;
                }
            }
            catch (System.Exception ex)
            {
                //LogDB.Exception.Add(ex);
                jsonParam.Add("PhotoIndex", "-99");
                jsonParam.Add("PhotoPath", "");
                outParam = jsonParam.ToString();
                _error = "翻拍发生了异常:" + ex.Message;
                Log.WriteException(_error);
                //OnWorkingFailed(outParam);
                return false;
            }
        }

        public override void Start(string param, out string outParam)
        {
            outParam = "";
            Log.WriteAsync("Start in");
            try
            {
                _cam.StartCameras();
                _bCapturing = true;
            }
            catch (System.Exception ex)
            {
                //LogDB.Exception.Add(ex);
                Log.WriteException(ex.ToString());
            }
            finally
            {
                Log.WriteAsync("Start out");
            }
        }

        public override void Stop(string param, out string outParam)
        {
            Log.WriteAsync("Stop in");
            outParam = "";
            if (_bCapturing)
            {
                _bCapturing = false;
                _cam.StopCameras();
            }
            else
            {
                Log.WriteAsync("Not Capturing");
            }
            Log.WriteAsync("Stop out");
        }

        public override void Exit(string inParams, out string outParam)
        {
            _bExited = true;
            outParam = "";
            if (Inited && null != _cam)
            {
                if (_cam.bStartCameras)
                {
                    _cam.newFrame -= NewRev;
                    _cam.StopCameras();
                }
            }
            _bInited = false;
            shareMem.Close();
        }

        public override void ShowConfigDialog(string inParam)
        {
            FormSetting form = new FormSetting();
            form.ShowDialog();
        }

        private void NewRev(object sender, NewFrameEventArgs eventArgs)
        {
            if (_cam.bStartCameras)
            {
                lock (lockflag)
                {
                    imgSourceData = IPCCom.Bitmap2ByteArray(eventArgs.Frame);
                    shareMem.CopyData2Mem(imgSourceData);
                }
            }
        }

        /// <summary>
        /// 执行资料翻拍动作，保存照片到本地
        /// </summary>
        /// <param name="fileName">照片完整路径</param>
        /// <returns></returns>
        private bool OnPhotoTaken(string fileName)
        {
            Log.WriteAsync("OnPhotoTaken in...");
            try
            {
                lock (lockflag)
                {
                    if (imgSourceData == null)
                    {
                        return false;
                    }
                    MemoryStream ms = new MemoryStream(imgSourceData);
                    Bitmap bitmap = new Bitmap(ms);
                    if (null == bitmap)
                    {
                        return false;
                    }
                    bitmap.Save(fileName, ImageFormat.Jpeg);
                    bitmap.Dispose();
                    bitmap = null;
                    ms.Close();
                    ms.Dispose();
                    ms = null;
                    Log.WriteAsync("OnPhotoTaken out.");
                    return true;
                }
            }
            catch (System.Exception ex)
            {
                //LogDB.Exception.Add(ex);
                Log.WriteException(ex.ToString());
                return false;
            }
        }
    }
}
